package com.lagou.rpc.client;

import com.alibaba.druid.pool.DruidDataSource;
import com.lagou.rpc.zk.ChildListener;
import com.lagou.rpc.zk.ZkClient;
import org.apache.commons.io.IOUtils;
import org.apache.curator.framework.api.CuratorWatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.StringReader;
import java.util.List;
import java.util.Properties;

/**
 * 项目启动时，加载appllicaiton.properties,放入zk。
 */
@Component
public class DemoRunner implements CommandLineRunner {

    @Autowired
    private ZkClient zkClient;

    @Override
    public void run(String... args) throws Exception {
        String path = "/spring/datasource/application.cfg";
        boolean exist = zkClient.exists(path);
        if (!exist) {
            ClassPathResource resource = new ClassPathResource("application.properties");
            zkClient.create(path, IOUtils.toString(resource.getInputStream()), true);
        }
        DruidDataSource dataSource = zkDataSource(path);
        ThreadDataSource.set(dataSource);

        /**
         * 以下开始设置监听器
         */
        CuratorWatcher watcher = zkClient.createChildListener("/spring/datasource", new ChildListener() {
            @Override
            public void childChanged(String path, List<String> child) {
                if (child.isEmpty()) {
                    return ;
                }
                DruidDataSource old = ThreadDataSource.get();
                if (old != null) {
                    old.close();
                }
                //设定 /spring/datasource只有一个子文件
                try {
                    String tmp = path +"/" + child.get(0);
                    ThreadDataSource.set(zkDataSource(tmp));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        zkClient.addChildListener("/spring/datasource", watcher);
    }

    /**
     * 从zk获取dataSource
     * @param path
     * @return
     * @throws Exception
     */
    DruidDataSource zkDataSource(String path) throws  Exception {
        String content = zkClient.getContent(path);
        Properties properties = new Properties();
        properties.load(new StringReader(content));
        String url = properties.getProperty("spring.datasource.url");
        String username = properties.getProperty("spring.datasource.username");
        String password = properties.getProperty("spring.datasource.password");
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);

        return ds;
    }

}
